import base64
import json

import pickle
from django import http
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from goods.models import SKU
from utils.response_code import RET


class CartsView(View):
    def post(self,request):
        user=request.user
        json_dict=json.loads(request.body.decode())
        sku_id=json_dict.get('sku_id')
        count=json_dict.get('count')
        selected=json_dict.get('selected',True)#若没有值，赋值True
        if not all([sku_id,count]):
            return http.HttpResponseForbidden('缺少必传参数')
        try:
            #取到商品
            sku=SKU.objects.get(id=sku_id)
        except Exception as e:
            return http.JsonResponse({'code':RET.PARAMERR, 'errmsg': '商品编号有误'})
        try:
            #取到数量
            count=int(count)
        except Exception as e:
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '数量有误'})
        if not isinstance(selected,bool):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '选择状态有误'})

        if user.is_authenticated:
            # 用户已登录，操作redis购物车
            redis_conn=get_redis_connection('carts')
            #取{sku_id:5},
            cart_dict=redis_conn.hgetall('carts_%s'%user.id)
            #cart_dict中数据为bytes类型，sku_id需转码一致
            if str(sku_id).encode() in cart_dict:
                count+=int(cart_dict[str(sku_id).encode()])
            redis_conn.hset('carts_%s'%user.id,sku.id,count)
            if selected:
                redis_conn.sadd('selected_%s'%user.id,sku.id)
            else:
                redis_conn.srem('selected_%s'%user.id,sku.id)
            return http.JsonResponse({'code':RET.OK,'errmsg':'数据存储成功'})
        else:
            # 用户未登录，操作cookie购物车
            # 保存在cookie中
            # {
            #     "sku_id1":{
            #         "count":"1",
            #         "selected":"True"
            #     },
            # }
            #取一下已经存在的购物车
            cart_base64 = request.COOKIES.get('carts')
            if cart_base64:
                cart_dict=pickle.loads(base64.b64decode(cart_base64))
            else:
                cart_dict={}
            if sku_id in cart_dict:
                count+=int(cart_dict[sku_id]['count'])
            cart_dict[sku.id]={'count':count,'selected':selected}
            res=http.JsonResponse({'code':RET.OK,'errmsg':'数据存储成功'})
            data_base64=base64.b64encode(pickle.dumps(cart_dict))
            res.set_cookie('carts',data_base64)
            return res
    def get(self, request):
        user = request.user
        if user.is_authenticated:
            # # 用户已登录，查询redis购物车
            #合并购物车
            cart_base64=request.COOKIES.get('carts')
            redis_conn=get_redis_connection('carts')
            if cart_base64:
                cart_dict=pickle.loads(base64.b64decode(cart_base64))
                for sku_id,count_selected in cart_dict.items():
                    redis_conn.hset('carts_%s' % user.id, sku_id,count_selected['count'])
                    if count_selected['selected']:
                        redis_conn.sadd('selected_%s' % user.id, sku_id)
                    else:
                        redis_conn.srem('selected_%s' % user.id, sku_id)
            cart_dict=redis_conn.hgetall('carts_%s'%user.id)# {sku_id:count}>>{b'16': b'1', b'15': b'1', b'14': b'1'}
            cart_selected_list=redis_conn.smembers('selected_%s'%user.id)# [sku_id]
            skus = []
            for sku_id,count in cart_dict.items():
                sku=SKU.objects.get(id=sku_id)
                sku_data={
                    'id':sku.id,
                    'default_image_url':sku.default_image_url.url,
                    'name':sku.name,
                    'price':int(sku.price), #转成十进制整数方便方便json解析
                    'amount':int(sku.price * int(count)), #通过key取value
                    'selected':str(sku_id in cart_selected_list),  # True 或者Flase True转'True',和js的数据格式保持一致
                    'count':int(count),
                }
                skus.append(sku_data)
            context={
                "cart_skus": json.dumps(skus)
                #前端模板需要一个json字符串而不是字典
            }
            res=render(request,'cart.html',context=context)
            res.delete_cookie('carts')
            return res

        else:
            # 用户未登录，查询cookies购物车
            # res = http.JsonResponse({'code': RET.OK, 'errmsg': '数据存储成功'})
            # data_base64 = base64.b64encode(pickle.dumps(data))
            # res.set_cookie('carts', data_base64)
            try:
                cart_base64=request.COOKIES.get('carts')
                cart_dict=pickle.loads(base64.b64decode(cart_base64))
                skus=[]
                for sku_id,count_selected in cart_dict.items():
                    sku=SKU.objects.get(id=sku_id)
                    sku_data={
                        'id':sku.id,
                        'selected':str(count_selected['selected']),
                        'default_image_url':sku.default_image_url.url,
                        'name':sku.name,
                        'price':int(sku.price),
                        'count':int(count_selected['count']),
                        'amount':int(sku.price * int(count_selected['count']))
                    }
                    skus.append(sku_data)
                context={
                        'cart_skus':json.dumps(skus)
                    }
                return render(request,'cart.html',context=context)
            except Exception as e:
                return render(request, 'cart.html')
    def put(self,request):
        user=request.user
        data=json.loads(request.body.decode())
        sku_id=data.get('sku_id')
        count=data.get('count')
        selected=data.get('selected')
        if not all([sku_id,count]):
            return http.HttpResponseForbidden('缺少必传参数')
        try:
            #取到商品
            sku=SKU.objects.get(id=sku_id)
        except Exception as e:
            return http.JsonResponse({'code':RET.PARAMERR, 'errmsg': '商品编号有误'})
        try:
            #取到数量
            count=int(count)
        except Exception as e:
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '数量有误'})
        if not isinstance(selected,bool):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '选择状态有误'})
        if user.is_authenticated():
            redis_conn = get_redis_connection('carts')
            redis_conn.hset('carts_%s'%user.id,sku_id,count)
            if selected:
                redis_conn.sadd('selected_%s'%user.id,sku_id)
            else:
                redis_conn.srem('selected_%s'%user.id,sku_id)
            cart_sku={
                'sku_id':sku_id,
                'count':count,
                'selected':selected
            }
            return http.JsonResponse({'code':RET.OK,'errmsg':'修改成功','cart_sku':cart_sku})
        else:
            # 用户未登录，修改cookie购物车
            cart_base64=request.COOKIES.get('carts')
            if cart_base64:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict=pickle.loads(base64.b64decode(cart_base64))
            else:
                cart_dict={}
            # 直接覆盖cookie中相关产品的数据
            cart_dict[sku_id]['count'] = count
            cart_dict[sku_id]['selected'] = selected
            cart_sku={
                'id': sku_id,
                'count': count,
                'selected': selected
            }
            res=http.JsonResponse({'code':RET.OK,'errmsg':'修改成功','cart_sku':cart_sku})
            cart_base64 = base64.b64encode(pickle.dumps(cart_dict))
            res.set_cookie('carts',cart_base64)
            return res

    def delete(self, request):
        user=request.user
        data=json.loads(request.body.decode())
        sku_id=data.get('sku_id')
        try:
            sku=SKU.objects.get(id=sku_id)
        except Exception as e:
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '商品编号有误'})
        #登陆用户
        if user.is_authenticated:
            redis_conn=get_redis_connection('carts')
            redis_conn.hdel('carts_%s' % user.id, sku_id)
            redis_conn.srem('selected_%s' % user.id, sku_id)
            return http.JsonResponse({'code':RET.OK,'errmsg':'删除成功'})
        else:
            #未登录用户
            cart_base64=request.COOKIES.get('carts')
            if cart_base64:
                cart_dict=pickle.loads(base64.b64decode(cart_base64))
            else:
                cart_dict={}
            if sku_id in cart_dict:
                cart_dict.pop(sku_id)
            cart_base64=base64.b64encode(pickle.dumps(cart_dict))
            res=http.JsonResponse({'code':RET.OK,'errmsg':'删除成功'})
            res.set_cookie('carts',cart_base64)
            return res

class CartsSelectAllView(View):
    # 全选购物车
    def put(self,request):
        user=request.user
        data=json.loads(request.body.decode())
        selected=data.get('selected')
        if not isinstance(selected,bool):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '选择状态有误'})
        if user.is_authenticated:
            redis_conn=get_redis_connection('carts')
            carts_dict=redis_conn.hgetall('carts_%s' % user.id)# {sku_id1:1, sku_id2: 2}
            sku_ids=carts_dict.keys()#[sku_id1, sku_id2]
            if selected:
                redis_conn.sadd('selected_%s'%user.id,*sku_ids) #sku_id1, sku_id2
            else:
                redis_conn.srem('selected_%s'%user.id,*sku_ids)
            return http.JsonResponse({'code':RET.OK,'errmsg':'全选成功'})

        else:
            carts_base64=request.COOKIES.get('carts')
            if carts_base64:
                # {sku_id:{'count':1,'selected': True},sku_id:{'count':1,'selected': True}}
                carts_dict=pickle.loads(base64.b64decode(carts_base64))
            else:
                carts_dict={}
            for sku_id,count_selected in carts_dict.items():
                count_selected['selected']=selected
            res=http.JsonResponse({'code':RET.OK,'errmsg':'成功'})
            carts_base64=base64.b64encode(pickle.dumps(carts_dict))
            res.set_cookie('carts',carts_base64)
            return res

class CartsSimpleView(View):
    #简易购物车
    def get(self,requests):
        user=requests.user
        # data=json.loads(requests.body.decode())
        '''{
            "code":"0",
            "errmsg":"OK",
            "cart_skus":[
                {
                    "id":1,
                    "name":"Apple MacBook Pro 13.3英寸笔记本 银色",
                    "count":1,
                    "default_image_url":"http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrPB4GAWkTlAAGuN6wB9fU4220429"
                },
            ]
        }'''
        # 用户已登录，查询Redis购物车
        if user.is_authenticated():
            redis_conn=get_redis_connection('carts')
            carts_dict=redis_conn.hgetall('carts_%s'%user.id)
            cart_skus=[]
            for sku_id,count in carts_dict.items():
                sku=SKU.objects.get(id=sku_id)
                sku_data={
                    'id':sku.id,
                    'name':sku.name,
                    'count':int(count),
                    'default_image_url':sku.default_image_url.url
                }
                cart_skus.append(sku_data)
            return http.JsonResponse({'code':RET.OK,'errmsg':'成功','cart_skus':cart_skus})

        # 用户未登录，查询cookie购物车
        else:
            cart_base64=requests.COOKIES.get('carts')
            if cart_base64:
                carts_dict=pickle.loads(base64.b64decode(cart_base64))
            else:
                carts_dict={}
            cart_skus = []
            for sku_id,count_selected in carts_dict.items():
                sku=SKU.objects.get(id=sku_id)
                sku_data={
                    'id': sku.id,
                    'name': sku.name,
                    'count': count_selected['count'],
                    'default_image_url': sku.default_image_url.url
                }
                cart_skus.append(sku_data)
            return http.JsonResponse({'code':RET.OK,'errmsg':'成功','cart_skus':cart_skus})



